#include<iostream>
#include<queue>
#include<pthread.h>
using namespace std;


#define THREAD_NUM 5
template<class T>
class ThreadPool
{
public:
  ThreadPool() 
  {
    pthread_mutex_init(&_mtx,nullptr);
    pthread_cond_init(&_cond,nullptr);
  }
  ~ThreadPool()
  {
    pthread_mutex_destroy(&_mtx);
    pthread_cond_destroy(&_cond);
  }
  bool empty() const 
  {
    return task_queue.empty();
  }
 
  void push(const T& task)
  {
      pthread_mutex_lock(&_mtx);
      task_queue.push(task);
      pthread_cond_signal(&_cond);
      pthread_mutex_unlock(&_mtx);
  }
  void pop(T* task)
  {
    *task = task_queue.front();
    task_queue.pop();
  }
  static void* Routine(void* arg)
  {
    pthread_detach(pthread_self());
    ThreadPool<T>* tp = static_cast<ThreadPool<T>*>(arg);
    while(1)
    {
      pthread_mutex_lock(&tp->_mtx);
      while(tp->empty())
      {
        pthread_cond_wait(&tp->_cond,&tp->_mtx);
      }
      T task;
      tp->pop(&task);
      pthread_mutex_unlock(&tp->_mtx);//记得解锁！！！
      task();
    }
  }
  void InitThreadPool()
  {
    pthread_t tid;
    for(int i = 0;i<THREAD_NUM;i++)
    {
      pthread_create(&tid,nullptr,Routine,(void*)this);
    }
  }
private:
  queue<T> task_queue;
  pthread_mutex_t _mtx;
  pthread_cond_t _cond;
};

